package demo.isolib {

	import com.greensock.easing.Back;
	import com.sshc625.utils.ArrayUtil;
	
	import de.polygonal.ds.NullIterator;
	
	import demo.isolib.Tile;
	
	public class TileManager {
		
		private static var hasInstance:Boolean = false;
		private static var instance:TileManager = null;
		
		private var _tiles:Array = [];
		
		public function TileManager() {
			if (!TileManager.hasInstance) {
				throw(new Error("TileManager is a singleton class, use getInstance() instead!"));
			}
			TileManager.hasInstance = false;
			this.empty();
		}
		
		public static function getInstance():TileManager {
			if (TileManager.instance == null) {
				TileManager.hasInstance = true;
				TileManager.instance = new TileManager();
			}
			return TileManager.instance;
		}
		
		// ====================================================================================
		public function getTileByName(name:String):Array {
			var arr:Array = [];
			for(var i:int=0; i<this._tiles.length; i++) {
				if( (this._tiles[i] as Tile).name == name) {
					arr.push( (this._tiles[i] as Tile) );
				}
			}
			return arr;
		}
		
		public function getTileByISOPosition(column:Number, row:Number):Array {
			var arr:Array = [];
			for(var i:int=0; i<this._tiles.length; i++) {
				if( (this._tiles[i] as Tile).column==column && (this._tiles[i] as Tile).row==row) {
					arr.push( (this._tiles[i] as Tile) );
				}
			}
			return arr;
		}	
		public function getTileByStagePosition(x:Number, y:Number, z:Number=0):Tile {
			throw new Error("getTileByStagePosition is TODO function");
			return null;
		}
		
		
		public function getWalkableTiles():Array {
			var arr:Array = [];
			for(var i:int=0; i<this._tiles.length; i++) {
				if( (this._tiles[i] as Tile).walkable) {
					arr.push((this._tiles[i] as Tile));
				}
			}
			return arr;
		}
		
		public function getIdleTiles():Array {
			var arr:Array = [];
			for(var i:int=0; i<this._tiles.length; i++) {
				if( (this._tiles[i] as Tile).isIdle) {
					arr.push((this._tiles[i] as Tile));
				}
			}
			return arr;
		}
		
		public function getSelectedTiles():Array {
			var arr:Array = [];
			for(var i:int=0; i<this._tiles.length; i++) {
				if( (this._tiles[i] as Tile).selected) {
					arr.push((this._tiles[i] as Tile));
				}
			}
			return arr;
		}
		/**
		 * 
		 */
		public function hasSelectedTiles():Boolean {
			return (this.getSelectedTiles().length > 0);
		}
		public function getSelectableTiles():Array {
			var arr:Array = [];
			for(var i:int=0; i<this._tiles.length; i++) {
				if( (this._tiles[i] as Tile).selectable) {
					arr.push((this._tiles[i] as Tile));
				}
			}
			return arr;
		}		

		// ====================================================================================
		
		/**
		 * Add tile.
		 * 
		 * @parameter tile	
		 * @return boolean. true indicate the tile be added, otherwise the tile existed
		 */
		public function addTile(tile:Tile):Boolean {
			var b:Boolean = this.hasTile( tile )
			if( !b ) {
				this._tiles.push( tile );
			}
			return b;
		}
		
		/**
		 * Has specific tile or not.
		 * 
		 * @return boolean true indicate has, otherwise no.
		 */
		public function hasTile(tile:Tile):Boolean {
			return ArrayUtil.arrayContainsValue(this._tiles, tile);
		}
		
		public function removeTile(tile:Tile):Boolean{
			var b:Boolean = this.hasTile(tile);
			if(b) {
				ArrayUtil.removeValueFromArray(this._tiles, tile);
			}
			return b;
		}		
		/**
		 * @return true indicate there is no tile in the manager.
		 */
		public function isEmpty():Boolean{
			return (this._tiles.length == 0);
		}
		
		public function empty():void {
			this._tiles = [];
		}
	}
}